/*
 * 简单的ReactOS字符设备驱动示例
 * 这个驱动实现了一个基本的字符设备，支持读写操作
 */

#include <ntddk.h>
#include <wdf.h>

// 设备扩展结构
typedef struct _DEVICE_EXTENSION {
    PDEVICE_OBJECT DeviceObject;
    UNICODE_STRING DeviceName;
    UNICODE_STRING SymbolicLinkName;
    // 设备缓冲区
    UCHAR Buffer[256];
    ULONG BufferLength;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

// 函数声明
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;
DRIVER_DISPATCH DeviceCreate;
DRIVER_DISPATCH DeviceRead;
DRIVER_DISPATCH DeviceWrite;
DRIVER_DISPATCH DeviceClose;

// 驱动入口点
NTSTATUS DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
) {
    NTSTATUS status;
    PDEVICE_OBJECT DeviceObject = NULL;
    PDEVICE_EXTENSION DeviceExtension;
    UNICODE_STRING DeviceName;
    UNICODE_STRING SymbolicLinkName;

    UNREFERENCED_PARAMETER(RegistryPath);

    // 设置驱动卸载函数
    DriverObject->DriverUnload = DriverUnload;

    // 设置主要分发函数
    DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreate;
    DriverObject->MajorFunction[IRP_MJ_READ] = DeviceRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = DeviceWrite;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceClose;

    // 初始化设备名称和符号链接名称
    RtlInitUnicodeString(&DeviceName, L"\\Device\\SimpleCharDevice");
    RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\SimpleCharDevice");

    // 创建设备对象
    status = IoCreateDevice(
        DriverObject,
        sizeof(DEVICE_EXTENSION),
        &DeviceName,
        FILE_DEVICE_UNKNOWN,
        0,
        FALSE,
        &DeviceObject
    );

    if (!NT_SUCCESS(status)) {
        DbgPrint("IoCreateDevice failed with status 0x%X\n", status);
        return status;
    }

    // 初始化设备扩展
    DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    DeviceExtension->DeviceObject = DeviceObject;
    RtlCopyUnicodeString(&DeviceExtension->DeviceName, &DeviceName);
    RtlCopyUnicodeString(&DeviceExtension->SymbolicLinkName, &SymbolicLinkName);
    DeviceExtension->BufferLength = 0;

    // 设置设备为缓冲IO模式
    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    // 创建符号链接
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status)) {
        DbgPrint("IoCreateSymbolicLink failed with status 0x%X\n", status);
        IoDeleteDevice(DeviceObject);
        return status;
    }

    DbgPrint("SimpleCharDevice driver loaded successfully!\n");
    return STATUS_SUCCESS;
}

// 驱动卸载函数
VOID DriverUnload(_In_ PDRIVER_OBJECT DriverObject) {
    PDEVICE_OBJECT DeviceObject;
    PDEVICE_EXTENSION DeviceExtension;

    // 获取设备对象列表
    DeviceObject = DriverObject->DeviceObject;
    while (DeviceObject != NULL) {
        DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

        // 删除符号链接
        IoDeleteSymbolicLink(&DeviceExtension->SymbolicLinkName);
        
        // 删除设备对象
        DeviceObject = DeviceObject->NextDevice;
        IoDeleteDevice(DeviceExtension->DeviceObject);
    }

    DbgPrint("SimpleCharDevice driver unloaded successfully!\n");
}

// 创建设备处理函数
NTSTATUS DeviceCreate(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp
) {
    UNREFERENCED_PARAMETER(DeviceObject);

    // 完成IRP请求
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("DeviceCreate: Device opened\n");
    return STATUS_SUCCESS;
}

// 读取设备处理函数
NTSTATUS DeviceRead(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp
) {
    PIO_STACK_LOCATION IoStackLocation;
    PDEVICE_EXTENSION DeviceExtension;
    ULONG ReadLength;
    ULONG BytesToRead;
    PVOID UserBuffer;

    // 获取IRP栈位置
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    
    // 获取用户缓冲区和读取长度
    UserBuffer = Irp->UserBuffer;
    ReadLength = IoStackLocation->Parameters.Read.Length;
    
    // 获取设备扩展
    DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    
    // 计算实际读取的字节数
    BytesToRead = min(ReadLength, DeviceExtension->BufferLength);
    
    // 复制数据到用户缓冲区
    if (BytesToRead > 0) {
        RtlCopyMemory(UserBuffer, DeviceExtension->Buffer, BytesToRead);
    }
    
    // 完成IRP请求
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = BytesToRead;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    DbgPrint("DeviceRead: Read %lu bytes\n", BytesToRead);
    return STATUS_SUCCESS;
}

// 写入设备处理函数
NTSTATUS DeviceWrite(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp
) {
    PIO_STACK_LOCATION IoStackLocation;
    PDEVICE_EXTENSION DeviceExtension;
    ULONG WriteLength;
    ULONG BytesToWrite;
    PVOID UserBuffer;

    // 获取IRP栈位置
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    
    // 获取用户缓冲区和写入长度
    UserBuffer = Irp->UserBuffer;
    WriteLength = IoStackLocation->Parameters.Write.Length;
    
    // 获取设备扩展
    DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    
    // 计算实际写入的字节数
    BytesToWrite = min(WriteLength, sizeof(DeviceExtension->Buffer));
    
    // 从用户缓冲区复制数据
    if (BytesToWrite > 0) {
        RtlCopyMemory(DeviceExtension->Buffer, UserBuffer, BytesToWrite);
        DeviceExtension->BufferLength = BytesToWrite;
    }
    
    // 完成IRP请求
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = BytesToWrite;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    DbgPrint("DeviceWrite: Wrote %lu bytes\n", BytesToWrite);
    return STATUS_SUCCESS;
}

// 关闭设备处理函数
NTSTATUS DeviceClose(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp
) {
    UNREFERENCED_PARAMETER(DeviceObject);
    
    // 完成IRP请求
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    DbgPrint("DeviceClose: Device closed\n");
    return STATUS_SUCCESS;
}

/* EOF */